package com.manli.api.controller;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.manli.api.base.config.JwtAuthTokenTimeConfig;
import com.manli.api.pojo.QueryParamsRefreshToken;
import org.apache.catalina.manager.util.SessionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.manli.api.base.exception.MyException;
import com.manli.api.dto.User;
import com.manli.api.enums.AuthEnums;
import com.manli.api.enums.ResultEnums;
import com.manli.api.pojo.Result;
import com.manli.api.pojo.SessionInfo;
import com.manli.api.service.LoginService;
import com.manli.api.service.UserPermissionService;
import com.manli.api.util.JwtUtils;
import com.manli.api.util.ResultUtil;
import com.manli.api.util.SessionInfoUtils;
import com.manli.common.utils.RandomUtils;

import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;


@Controller
@Api(tags="用户登陆")
public class LoginController {
	Logger logger = LoggerFactory.getLogger(getClass());

	
	
	@Autowired
	LoginService loginService;
	@Autowired
	UserPermissionService userPermissionService;
	@SuppressWarnings("rawtypes")
	@Autowired
	RedisTemplate redisTemplate;
	@Autowired
	SessionInfoUtils sessionInfoUtils;
	
//	/**
//	 * session登录
//	 * @return
//	 */
//	@RequestMapping(value="/login/loginForSession")
//	public String loginForSession(HttpServletRequest request,HttpServletResponse response,User user) throws Exception{
//		SessionInfo sessionInfo = loginService.getSessionInfoByNameAndPasswd(user,request);
//		if(sessionInfo!=null) {
//			request.getSession().setAttribute(AuthEnums.AUTH_SESSION.getContent(), sessionInfo);
//			return "redirect:/index_old.html";
//		}
//		return "redirect:/login.html";
//	}

	/**
	 * session退出登录
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@PostMapping(value="/login/logoutForSession")
	public @ResponseBody Result logoutForSession(HttpServletRequest request,HttpServletResponse response) {
		request.getSession().setAttribute(AuthEnums.AUTH_SESSION.getContent(),null);
		/**
		 * 清除auth_token
		 */
		SessionInfo sessionInfo = sessionInfoUtils.getSessionInfoByAuth(request);
		if (sessionInfo!=null) {
			if (redisTemplate.hasKey("auth_token:"+sessionInfo.getUserId()+":"+sessionInfo.getName())) {
				redisTemplate.opsForValue().set("auth_token:"+sessionInfo.getUserId()+":"+sessionInfo.getName(),null);
			}
		}
		return ResultUtil.success("感谢您使用本系统,期待下次相会");
	}
	/**
	 * auth_token登录
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@PostMapping(value="/login/loginForToken")
	public @ResponseBody Result loginForToken(HttpServletRequest request,HttpServletResponse response,@RequestBody User user)throws Exception {
		SessionInfo sessionInfo = loginService.getSessionInfoByNameAndPasswd(user,request);
		if(sessionInfo!=null) {
			JSONObject object = loginService.getAuthToken(sessionInfo);
			return ResultUtil.success(object);
		}
		return ResultUtil.error(ResultEnums.NO_LOGIN_ERR_LOGIN_Info.getCode(), ResultEnums.NO_LOGIN_ERR_LOGIN_Info.getMsg());
	}
	
	@SuppressWarnings("unchecked")
	@PostMapping(value="/login/loginForRefreshToken")
	public @ResponseBody Result loginForRefreshToken(HttpServletRequest request,HttpServletResponse response,@RequestBody QueryParamsRefreshToken refreshToken)throws Exception {
		/**
		 * 判断refresh是否有效
		 * 如果有效怎刷新auth_token ，如果无效就报错 提示refresh_token过期 去登陆
		 */
		Claims claims = JwtUtils.verifyJwt(refreshToken.getRefreshToken());
		if (claims!=null) {
			//有效 怎生产一个新的auto_token refresh_token redis延期
			String userId = claims.get("userId").toString();
			String userName = claims.get("userName").toString();
			SessionInfo sessionInfo = (SessionInfo) redisTemplate.opsForValue().get("auth_token:"+userId+":"+userName);
			
			Map<String,Object> newclaims = new HashMap<String, Object>();
			newclaims.put("userId", sessionInfo.getUserId());
			newclaims.put("userName", sessionInfo.getName());
			String auth_token = JwtUtils.createJWT(newclaims, JwtAuthTokenTimeConfig.JwtAuthTokenExpireTime);
			newclaims.put("randomNum", RandomUtils.getRandNumByLength(10));
			String refresh_token = JwtUtils.createJWT(newclaims, JwtAuthTokenTimeConfig.JwtRefreshTokenExpireTime);
			//sessionInfo存入redis
			redisTemplate.opsForValue().set("auth_token:"+sessionInfo.getUserId()+":"+sessionInfo.getName(), sessionInfo,JwtAuthTokenTimeConfig.JwtAuthTokenRedisExpireTime,TimeUnit.SECONDS);
			JSONObject object = new JSONObject();
			object.put("auth_token", auth_token);
			object.put("refresh_token", refresh_token);
			object.put("menus",userPermissionService.getUserPermissionVue(sessionInfo.getUserId(),sessionInfo.getBranchId()));
			object.put("sessionInfo",sessionInfo);
			return ResultUtil.success(object);
		}else {
			throw new MyException(ResultEnums.NO_LOGIN_REFRESH_TOKEN_IS_EXPIRE);
		}
	}
	
}